package com.harmontronics.hanma.paas.paas.domain.app.repository.persistence;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.harmontronics.hanma.paas.paas.consts.DbConstants;
import com.harmontronics.hanma.paas.paas.domain.app.entity.valueobject.Fields;
import com.harmontronics.hanma.paas.paas.domain.app.repository.mapper.HmModelMapper;

import com.harmontronics.hanma.paas.paas.domain.app.repository.po.HmModelPO;
import com.harmontronics.hanma.paas.paas.domain.app.repository.po.HmVirtualModelPO;
import com.harmontronics.hanma.paas.paas.domain.app.service.dialect.PostgresDialectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.StringJoiner;


@Repository("hmModelRepository")
public class HmModelRepository extends ServiceImpl<HmModelMapper, HmModelPO> {

    @Autowired
    private PostgresDialectService postgresDialectService;

    public IPage<HmModelPO> selectPage(QueryWrapper<HmModelPO> queryWrapper, Page<HmModelPO> page) {
        return baseMapper.selectPage(page, queryWrapper);
    }

    public HmModelPO findByCode(String code) {
        QueryWrapper<HmModelPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", code);
        return baseMapper.selectOne(queryWrapper);
    }

    public HmModelPO findByName(String name) {
        QueryWrapper<HmModelPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", name);
        return baseMapper.selectOne(queryWrapper);
    }


    public boolean existByHttpServiceId(Long httpServiceId){
        QueryWrapper<HmModelPO> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq(Fields.HTTP_SERVICE_ID,httpServiceId);
        queryWrapper.last("limit 1");
        return baseMapper.selectCount(queryWrapper) > 0;
    }

    /**
     * 新建表
     *
     * @param tableName
     */
    public void createTable(String tableName) {
        baseMapper.createTable(tableName);
    }

    /**
     * 新建表 支持流程
     *
     * @param tableName
     */
    public void createTableWoProcess(String tableName) {
        baseMapper.createTableWoProcess(tableName);
    }


    public void dropTable(String tableName) {
        baseMapper.dropTable(tableName);
    }


    public Long dynamicInsert(String tableName, Map<String, Object> dataMap) {
        HmVirtualModelPO virtualModelPO = new HmVirtualModelPO();
        virtualModelPO.setTableName(tableName);
        StringJoiner keyJoiner = new StringJoiner(",");
        StringJoiner valueJoiner = new StringJoiner(",");
        for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
            keyJoiner.add(entry.getKey());
            valueJoiner.add(postgresDialectService.getValue(entry.getValue()));
        }
        virtualModelPO.setKeys(keyJoiner.toString());
        virtualModelPO.setValues(valueJoiner.toString());
        baseMapper.dynamicInsert(virtualModelPO);
        return virtualModelPO.getId();
    }

    public void dynamicInsertInBatch(String tableName, String keys, String values) {
        baseMapper.dynamicInsertInBatch(tableName,keys,values);
    }

    public void dynamicDelete(String tableName, Long id) {
        baseMapper.dynamicDelete(tableName, id);
    }

    public void dynamicTruncateData(String modelCode) {
        baseMapper.dynamicTruncateData(modelCode);
    }

    public void dynamicUpdate(String tableName, Map<String, Object> dataMap) {
        HmVirtualModelPO virtualModelPO = new HmVirtualModelPO();
        virtualModelPO.setTableName(tableName);
        virtualModelPO.setId(Long.parseLong(dataMap.get(DbConstants.ID).toString()));
        dataMap.remove(DbConstants.ID);
        StringJoiner keyJoiner = new StringJoiner(",");
        for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
            keyJoiner.add(entry.getKey() + "=" + postgresDialectService.getValue(entry.getValue()));
        }
        virtualModelPO.setKeys(keyJoiner.toString());
        baseMapper.dynamicUpdate(virtualModelPO);
    }

    public List<Map<String,Object>> dynamicList(String tableName,String whereSql,String orderSql,String limitSql){
        return baseMapper.dynamicListWithLimit(tableName,whereSql,orderSql,limitSql);
    }

    public List<Map<String,Object>> dynamicList(String tableName,Map<String,Object> params,List<String> orderRules){
        return baseMapper.dynamicList(tableName,postgresDialectService.getWhereStr(params),getOrderByStr(orderRules));
    }

    public IPage<Map<String,Object>> dynamicPageList(String tableName,Map<String,Object> params,List<String> orderRules,Page page){
        return baseMapper.dynamicPageList(tableName,postgresDialectService.getWhereStr(params),getOrderByStr(orderRules),page);
    }

    public IPage<Map<String,Object>> dynamicPageList(String tableName,String whereSqlSegment, String orderBySqlSegment,Page page){
        return baseMapper.dynamicPageList(tableName,whereSqlSegment,orderBySqlSegment,page);
    }

    public List<Map<String,Object>> dynamicGetByIds(String tableName,List<String> cloumns, List<String> idList){
        return baseMapper.dynamicGetByIds(tableName,String.join(",",cloumns),String.join(",",idList));
    }

    private String getOrderByStr(List<String> orderRules){
        if(CollectionUtils.isEmpty(orderRules)){
            return "create_date desc";
        }
        StringJoiner joiner=new StringJoiner(",");
        orderRules.forEach(joiner::add);
        return joiner.toString();
    }



    public Map<String, Object> dynamicGet(String tableName, Long id) {
        return baseMapper.dynamicGet(tableName,id);
    }

    public void createTableWoTree(String code) {
        baseMapper.createTableWoTree(code);
    }

    public List<Map<String, Object>> dynamicGetSubTableData(String tableName, String relationColumn, Long parentId) {
        return baseMapper.dynamicGetSubTableData(tableName,relationColumn,parentId);
    }


}